package com.hsu.easyweb.config;

import java.util.Objects;
import java.util.function.Predicate;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.RequestHandler;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * 配置类用于集成 Knife4j Swagger API 文档生成工具。
 * @ClassName: Knife4jConfig
 * @author Hsu琛君珩
 * @date 2024-09-09
 * @apiNote
 * @version v1.0
 */
@Configuration
@EnableSwagger2
@Profile({"!prod"})
@ConfigurationProperties("knife4j.config")
public class Knife4jConfig {
    private String title = "接口文档";
    private String description;
    private String version = "1.0";
    private String scanPath;
    private String name;
    private String email;
    private String url;

    @Bean
    public Docket defaultApi2() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(new ApiInfoBuilder().title(this.title)
                        .contact(new Contact(this.name, this.url, this.email))
                        .description(this.description)
                        .version(this.version)
                        .build())
                .select()
                .apis(this.selector(this.scanPath))
                .paths(PathSelectors.any())
                .build();
    }

    private Predicate<RequestHandler> selector(String scanPath) {
        return StringUtils.isBlank(scanPath)
                ? RequestHandlerSelectors.withClassAnnotation(RestController.class)
                .or(RequestHandlerSelectors.withClassAnnotation(Controller.class))
                : RequestHandlerSelectors.basePackage(scanPath);
    }

    public Knife4jConfig() {
    }

    public String getTitle() {
        return this.title;
    }

    public String getDescription() {
        return this.description;
    }

    public String getVersion() {
        return this.version;
    }

    public String getScanPath() {
        return this.scanPath;
    }

    public String getName() {
        return this.name;
    }

    public String getEmail() {
        return this.email;
    }

    public String getUrl() {
        return this.url;
    }

    public void setTitle(final String title) {
        this.title = title;
    }

    public void setDescription(final String description) {
        this.description = description;
    }

    public void setVersion(final String version) {
        this.version = version;
    }

    public void setScanPath(final String scanPath) {
        this.scanPath = scanPath;
    }

    public void setName(final String name) {
        this.name = name;
    }

    public void setEmail(final String email) {
        this.email = email;
    }

    public void setUrl(final String url) {
        this.url = url;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Knife4jConfig)) return false;
        Knife4jConfig that = (Knife4jConfig) o;
        return title.equals(that.title) &&
                description.equals(that.description) &&
                version.equals(that.version) &&
                scanPath.equals(that.scanPath) &&
                name.equals(that.name) &&
                email.equals(that.email) &&
                url.equals(that.url);
    }

    @Override
    public int hashCode() {
        return Objects.hash(title, description, version, scanPath, name, email, url);
    }

    @Override
    public String toString() {
        return "Knife4jConfig{" +
                "title='" + title + '\'' +
                ", description='" + description + '\'' +
                ", version='" + version + '\'' +
                ", scanPath='" + scanPath + '\'' +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", url='" + url + '\'' +
                '}';
    }
}
